<?php
/** Copyright 2014 TinPhp Systems, Inc.
 * @author zhangxilian 2013-1-20
 * @package TinPhp
 */
/**
 * Mysql数据库链接对象，使用Adodb5
 */
class TinDao_Mysql extends TinDaoBase {
	
	/** 实体化MysqlDAO类 
	 * @param db对象 $dbConn 数据库链接对象
	 * @param view类 $view 表、视图对象
	 * */
	public function TinDao_Mysql(& $dbConn, & $view) {
		$this->db = $dbConn;
		$this->view = $view;
		$this->table = $view->getTableStmt();
		$this->tableSeq = $view->getTableSeq();
		$this->tableId = $view->getId();
		$this->seqOff = $view->getSeqOff();
		$this->logger = new TinLogger(SQL_LOG_PATH, "TinDao_Mysql");
	}
	
	//===========================================================================================
	//********查************
	//===========================================================================================	
	/** 
	 * 根据条件分页查询记录，各个参数值列名都要是 列别名
	 * @param string $cols 指定列名
	 * @param string $cond 指定查询条件
	 * @param int $page 当前分页数，默认1
	 * @param int $size 每页数量,默认10条
	 * @param array $params 可以执行绑定变量使用 array类型
	 * @param string $extra 语句的最后附加条件
	 * @return array
	 * */
	public function selectByCond($cols, $cond, $page = 1, $size = 10, $params = false, $extra = null) {		
		try{
			$colStmt = $this->convColStmt($cols);
			
			$sql = "select " . $colStmt . " from " . $this->table. " ".$this->view->getTableLeftJoin();
	
			$condStmt = "";
			if ($this->view->isMultiple()) {
				$conj = $this->view->getTableStmtCond();
				$condStmt = $conj . " AND (" . $cond . ")";
			} else {
				$condStmt .= $cond;
			}
			
			if ($condStmt != "") {
				$sql .= " where " . $condStmt;
			}
			if($extra!=null){
				$sql .= ' '.$extra;
			}
			if ($page) {
				$startrow = ($page-1)<0 ? 0:($page-1);
				$sql .=" LIMIT ".($startrow * $size)." , ".$size;			
			}
			
			$this->logger->info("selectByCond:".$sql);
			$respArray = $this->db->GetAll($sql, $params);
			return $respArray;
		}catch(Exception $e){
			$this->logger->error("selectByCond:".$sql."\n ERROR:".$e->getMessage());
			throw new DBException("selectByCond Fail: ".$e->getMessage());
		}
	}
	
	//===========================================================================================
	//********增************
	//===========================================================================================
	/**
	 * 插入数据记录
	 * @param TinDataMap $zxData 数据对象 @see TinDataMap
	 * @param bool $checkDataType 是否检查数据类型，默认true
	 * @param bool $tick 是否返回最后的ID值，默认true
	 * @param array $params 可以执行绑定变量使用 array类型
     * @return int
	 */
	public function insert(& $zxData, $checkDataType = true, $tick = true, $params=false) {
		//验证数据类型
		if ($checkDataType == true && $zxData->checkTypeValid() == false) {
			$this->logger->error("insert:".$this->table . " insert checkTypeValid Fail");
			//echo $this->table . " insert checkTypeValid Fail";
			return false;
		}
		
		$cols = $zxData->getKeys();
		$vals = $zxData->getValues();
		$types = $zxData->getTypes();
		//$clobArr = array ();
		//$blobArr = array ();

		$colStmt = "";
		$colsNum = count($cols);
		for ($i = 0; $i < $colsNum; $i++) {
			$colStmt .= $cols[$i];
			if ($i < $colsNum -1) $colStmt .= ",";
		}

		$valStmt = "";
		$valsNum = count($vals);
		for ($i = 0; $i < $valsNum; $i++) {
			if(""!=$valStmt) $valStmt .=",";
			if ($this->needAppendQuote($types[$i])) {
				$valStmt .= $this->db->qstr($vals[$i]);
				//$valStmt .= "'" . $vals[$i] . "'";
			} else {
				$valStmt .= $vals[$i];
			}
		}
		
		$sql = "insert into " . $this->table . " (" . $colStmt . ") values(" . $valStmt . ")";
        try{
            $this->logger->info("insert:".$sql);
            $this->db->Execute($sql,$params);
            if($tick)
                return $this->getLastInsertId();
            else
                return true;
        }catch(Exception $e){
			$this->logger->error("insert:".$sql."\n ERROR:".$e->getMessage());
			throw new DBException("insert Fail: ".$e->getMessage());
		}
	}
	/**
	 * 获取最后插入ID
	 */
	public function getLastInsertId($table_name_seq = null) {	
        try{
            $this->logger->info("getLastInsertId:select LAST_INSERT_ID()");
            $id = $this->db->GetRow("select LAST_INSERT_ID() as lastid");
            return $id['lastid'];
        }catch(Exception $e){
			$this->logger->error("getLastInsertId:".$sql."\n ERROR:".$e->getMessage());
			throw new DBException("getLastInsertId Fail: ".$e->getMessage());
		}
	}
	//===========================================================================================
	//********改************
	//===========================================================================================
	/** 根据指定ID，更新数据记录
     * @param TinDataMap $zxData 数据对象 @see TinDataMap
     * @param int $id 指定数据ID
     * @param bool $checkDataType 是否检测数据类型，默认true
     * @return int
     * */
	public function updateByID(& $zxData, $id, $checkDataType = true){
        try{
            return $this->updateByCond($zxData, $this->view->getId()."=".$id, $checkDataType);
        }catch(Exception $e){
			$this->logger->error("updateByID:".$e->getMessage());
			throw new DBException("updateByID Fail: ".$e->getMessage());
		}
	}
    /** 根据条件更新数据，返回影响行数
     * @param TinDataMap $zxData 数据对象 @see TinDataMap
     * @param string $cond 查询条件(字段1=条件1 and 字段2=条件2)
     * @param bool $checkDataType 是否检测数据类型，默认true
     * @param bool $params 可以执行绑定变量使用 array类型
     * @param string $extra 语句的最后附加条件
     * @return int
     * */
	public function updateByCond(& $zxData, $cond, $checkDataType = true, $params = false, $extra = null) {
		if (is_null($cond) || $cond == "") {
			throw new DBException("updateByCond Fail: Lack of Condition when process update");
		}
		//验证数据类型
		if ($checkDataType == true && $zxData->checkTypeValid() == false) {
			$this->logger->error("updateByCond:".$this->table . " update checkTypeValid Fail");
			throw new DBException($this->table . " update checkTypeValid Fail");
		}

		$cols = $zxData->getKeys();
		$vals = $zxData->getValues();
		$types = $zxData->getTypes();
				
		$sql = "update " . $this->table . " set ";
		
		$fieldStr = "";
		$colsNum = count($cols);		
		for ($i = 0; $i < $colsNum; $i++) {
			if(""!=$fieldStr) $fieldStr.=",";
			$fieldStr .= $cols[$i] . " = ";
			if ($this->needAppendQuote($types[$i])) {
				$fieldStr .= $this->db->qstr($vals[$i]);
				//$fieldStr .= "'" . $vals[$i] . "'";
			} else {
				$fieldStr .= $vals[$i];
			}
		}
		
		$sql .= $fieldStr . " where " . $cond;
		$sqlStmt = $sql;
		if ($extra != null) {
			$sqlStmt .= " " . $extra;
		}		
		try{
            $this->logger->info("updateByCond:".$sqlStmt."   ".(is_array($params) ? "params:".implode('_',$params) :""));
			$this->db->Execute($sqlStmt, $params);
			return $this->db->GetRow("select row_count()");
		}catch(Exception $e){
			$this->logger->error("updateByCond:".$sql."\n ERROR:".$e->getMessage());
			throw new DBException("updateByCond:".$e->getMessage());
		}

	}
	
	//===========================================================================================
	//********删************
	//===========================================================================================	
	/** 根据指定条件，删除数据记录
     * @param string $cond 查询条件(字段1=条件1 and 字段2=条件2)
     * @param bool $params 可以执行绑定变量使用 array类型
     * @param string $extra 语句的最后附加条件
     * @return int
     * */
	public function deleteByCond($cond, $params = false, $extra = null) {
		$sql = "delete from " . $this->table . "  where " . $cond;
		if ($extra != null) {
			$sql .= " " . $extra;
		}
		try{
            $this->logger->info("deleteByCond:".$sql."   ".(is_array($params) ? "params:".implode('_',$params) :""));
			$this->db->Execute($sql, $params);
			return $this->db->GetRow("select row_count()");
		}catch(Exception $e){
			$this->logger->error("deleteByCond:".$sql."\n ERROR:".$e->getMessage());
			throw new DBException("deleteByCond Fail: ".$e->getMessage());
		}		
	}	

	
	
}//End Class
?>
